﻿#include "mainwindow.h"
#include "ColorComboBox.h"
#include "ui_mainwindow.h"
#include "./DisplayWidget/imagedisplay.h"
#include "./DisplayWidget/DisplayWidget.h"
#include "./DisplayWidget/element.h"
#include <QLabel>
#include <QDebug>
#include <QPushButton>
#include <QSpinBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include <QCheckBox>
#include "fitinnercircle.h"
#include "./qtOpenCV/convert.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //setAttribute(Qt::WA_DeleteOnClose);
    setWindowTitle("");
    ui->setupUi(this);
    m_centerWidget = new DisplayWidget(this);
    ui->scrollArea->setWidget(m_centerWidget);
    setupToolBar();
    setupAction();
    QString path = qApp->applicationDirPath();
    QSettings settings( path + "/scale.ini", QSettings::IniFormat, this );

    initScale(settings);
    //ui->actionX5->setChecked(true);
    m_centerWidget->setDrawType(Element::LINE);
    connect(ui->actionOpen, SIGNAL(triggered(bool)), this, SLOT(loadImage()));
    connect(ui->actionSaveWithMark, SIGNAL(triggered()), this, SLOT(saveImagewithMark()));
    connect(ui->actionSaveWithoutMark, SIGNAL(triggered()), this, SLOT(saveImagewithoutMark()));

    uncheckAll();
    ui->actionLine->setChecked(true);
}

void MainWindow::autoMesure()
{
    QImage image = m_centerWidget->getImage(false);
    cv::Mat im = QImage2cvMat(image);
    double x, y, r;
    bool ret = fitInnerCircle(im, x, y, r, 160);
    if(ret)
    {
        m_centerWidget->addCircle(QPoint(x, y), r);
    }
}


void MainWindow::imageEnhance(void)
{
//    FilterTemplate filter;
//    filter.buildLaplaceFilter4();
//    m_centerWidget->setImage(filter.apply(m_centerWidget->getImage()));
//    m_centerWidget->update();
}


void  MainWindow::uncheckAll()
{
    ui->actionSelect->setChecked(false);
    ui->actionLine->setChecked(false);
    ui->actionParallel->setChecked(false);
    ui->actionLCircle->setChecked(false);
    ui->actionRCircle->setChecked(false);
    ui->actionRect->setChecked(false);
    ui->actionCorner->setChecked(false);
    ui->actionHTLine->setChecked(false);
    ui->actionVTLine->setChecked(false);
    ui->actionPolygon->setChecked(false);
    ui->actionPolyline->setChecked(false);
    ui->actionPCircle->setChecked(false);
}

void  MainWindow::test(bool)
{
    QAction * action = (QAction *) sender();
    uncheckAll();
    action->setChecked(true);
    if( action == ui->actionSelect )
    {
        m_centerWidget->setDrawType(Element::NONE);
    }
    else if(action == ui->actionLine)
    {
        m_centerWidget->setDrawType(Element::LINE);
    }
    else if(action == ui->actionParallel)
    {
        m_centerWidget->setDrawType(Element::PARALLEL);
    }
    else if(action == ui->actionLCircle)
    {
        m_centerWidget->setDrawType(Element::LCIRCLE);
    }
    else if(action == ui->actionRCircle)
    {
        m_centerWidget->setDrawType(Element::RCIRCLE);
    }
    else if(action == ui->actionRect)
    {
        m_centerWidget->setDrawType(Element::RECTAGLE);
    }
    else if(action == ui->actionCorner)
    {
        m_centerWidget->setDrawType(Element::CORNER);
    }
    else if(action == ui->actionHTLine)
    {
        m_centerWidget->setDrawType(Element::HTLINE);
    }
    else if(action == ui->actionVTLine)
    {
        m_centerWidget->setDrawType(Element::VTLINE);
    }
    else if(action == ui->actionPolyline)
    {
        m_centerWidget->setDrawType(Element::POLYLINE);
    }
    else if(action == ui->actionPolygon)
    {
        m_centerWidget->setDrawType(Element::POLYGON);
    }
    else if(action == ui->actionPCircle)
    {
        m_centerWidget->setDrawType(Element::PCIRCLE);
    }
}

void MainWindow::setupAction()
{
    connect(ui->actionSelect, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionLine, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionParallel, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionLCircle, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionRCircle, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionRect, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionCorner, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionHTLine, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionVTLine, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionPolygon, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionPolyline, SIGNAL(triggered(bool)), this, SLOT(test(bool)));
    connect(ui->actionPCircle, SIGNAL(triggered(bool)), this, SLOT(test(bool)));

    connect(ui->actionAutoMeasure, SIGNAL(triggered()), this, SLOT(autoMesure()));
}


void MainWindow::initScale(QSettings &settings)
{
    m_lens = X5;
    qDebug() << "m_lens = " << m_lens;
    m_scale[X2] = settings.value("PDStage/X2", 200).toDouble();
    m_scale[X5] = settings.value("PDStage/X5", 100).toDouble();
    m_scale[X10] = settings.value("PDStage/X10", 50).toDouble();
    m_scale[X20] = settings.value("PDStage/X20", 25).toDouble();
    m_scale[X50] = settings.value("PDStage/X50", 10).toDouble();
    m_scale[X100] = settings.value("PDStage/X100", 5).toDouble();
    qDebug() << "m_lens = " << m_lens;
    m_centerWidget->setScale(m_scale[m_lens]);
//    int line = settings.value("PDStage/Line", 100).toInt();
//    m_spinBoxLine->setValue(line);
//    m_centerWidget->setReferenceLine(line);
    qDebug() << "m_lens = " << m_lens;
    switch(m_lens)
    {
    case X2:ui->actionX2_5->setChecked(true);break;
    case X5:ui->actionX5->setChecked(true);break;
    case X10:ui->actionX10->setChecked(true);break;
    case X20:ui->actionX20->setChecked(true);break;
    default:ui->actionX5->setChecked(true);break;
    }
    connect(ui->actionX2_5, SIGNAL(triggered()), this, SLOT(lensUpdate(void)));
    connect(ui->actionX5, SIGNAL(triggered()), this, SLOT(lensUpdate(void)));
    connect(ui->actionX10, SIGNAL(triggered()), this, SLOT(lensUpdate(void)));
    connect(ui->actionX20, SIGNAL(triggered()), this, SLOT(lensUpdate(void)));

}

void MainWindow::lensUpdate(void)
{
    QAction *act = (QAction *) sender();
    QAction * actionArray[4];
    actionArray[X2] = ui->actionX2_5;
    actionArray[X5] = ui->actionX5;
    actionArray[X10] = ui->actionX10;
    actionArray[X20] = ui->actionX20;

    int old = m_lens;

    act->setChecked(true);
    for(int i = X2; i <= X20; i++)
    {
        if(act == actionArray[i] )
        {
            m_lens = (ZOOM)i;
            if(m_lens == old)
            {
                break;
            }
            // 表示真正切换了物镜
            actionArray[old]->setChecked(false); // 讲原先的物镜选择 uncheck
            m_centerWidget->setScale(m_scale[m_lens]);
            break;
        }
    }
}
void MainWindow::setupToolBar()
{
    //ui->toolBarMark->addSeparator();
    QLabel *label = new QLabel(QStringLiteral(" 线条宽度: "), this);
    ui->toolBarMarkSet->addWidget(label);
    QSpinBox *spinBox = new QSpinBox;
    spinBox->setRange(1, 10);
    spinBox->setValue(2);
    spinBox->setSingleStep(1);
    ui->toolBarMarkSet->addWidget(spinBox);
    ui->toolBarMarkSet->addSeparator();
    connect(spinBox, SIGNAL(valueChanged(int)), m_centerWidget, SLOT(setLineWidth(int)));

    label = new QLabel(QStringLiteral(" 文字大小: "), this);
    ui->toolBarMarkSet->addWidget(label);
    spinBox = new QSpinBox;
    spinBox->setRange(6, 30);
    spinBox->setValue(12);
    spinBox->setSingleStep(1);
    ui->toolBarMarkSet->addWidget(spinBox);
    ui->toolBarMarkSet->addSeparator();
    connect(spinBox, SIGNAL(valueChanged (int)), m_centerWidget, SLOT(setTextSize(int)));

    ColorComboBox *cb = new ColorComboBox();
    ui->toolBarMarkSet->addWidget(cb);
    connect(cb, SIGNAL(colorChanged(QColor)), m_centerWidget, SLOT(setColor(const QColor)));
    cb->setCurrentIndex(1);

    ui->toolBarMarkSet->addAction(ui->actionCalibrate);
    connect(ui->actionCalibrate, SIGNAL(triggered(bool)), this, SLOT(calibrate()));

    ui->toolBarMarkSet->addSeparator();
    ui->toolBarMarkSet->addAction(ui->actionUndo);
    ui->toolBarMarkSet->addAction(ui->actionDeleteAll);
    connect(ui->actionUndo, SIGNAL(triggered()), m_centerWidget, SLOT(undo()));
    connect(ui->actionDeleteAll, SIGNAL(triggered()), m_centerWidget, SLOT(clearAll()));

    label = new QLabel(QStringLiteral("显示比例: "), this);
    ui->toolBarDisplayZoom->addWidget(label);
    spinBox = new QSpinBox;
    spinBox->setSuffix(" %");
    spinBox->setRange(10, 500);
    spinBox->setValue(100);
    spinBox->setSingleStep(10);
    ui->toolBarDisplayZoom->addWidget(spinBox) ;
    connect(spinBox, SIGNAL(valueChanged(int)), m_centerWidget, SLOT(setZoomFactorPCT(int)));

    QCheckBox * checkBox = new QCheckBox(QStringLiteral("十"));
    ui->toolBarDisplayZoom->addWidget(checkBox) ;
    checkBox->setChecked(true);
    connect(checkBox, SIGNAL(toggled(bool)), m_centerWidget, SLOT(showCross(bool)));

//    m_spinBoxLine = new QSpinBox;
//    m_spinBoxLine->setRange(1, 1500);
//    m_spinBoxLine->setValue(100);
//    m_centerWidget->setReferenceLine(100);
//    m_spinBoxLine->setSingleStep(2);
//    ui->toolBarMark->addWidget(m_spinBoxLine);
//    connect(m_spinBoxLine, SIGNAL(valueChanged(int)), m_centerWidget, SLOT(setReferenceLine(int)));


}

void MainWindow::calibrate()
{
    bool ok;
    double len = m_centerWidget->getLength(ok);
    if(ok)
    {
        double real_len = QInputDialog::getDouble ( this, QStringLiteral("定标"), QStringLiteral("输入长度"), 1, 0.1, 10000, 1, &ok );
        if(ok)
        {
            m_scale[m_lens] = real_len / len;
            m_centerWidget->setScale(m_scale[m_lens]);
            QSettings settings( ".\\scale.ini", QSettings::IniFormat, this );
            switch(m_lens)
            {
            case X5:
                settings.setValue("PDStage/X5", m_scale[m_lens]);
                break;
            case X10:
                settings.setValue("PDStage/X10", m_scale[m_lens]);
                break;
            case X20:
                settings.setValue("PDStage/X20", m_scale[m_lens]);
                break;
            case X50:
                settings.setValue("PDStage/X50", m_scale[m_lens]);
                break;
            case X100:
                settings.setValue("PDStage/X100", m_scale[m_lens]);
                break;
            }
        }
    }
    else
    {
        QMessageBox::information(this, QStringLiteral("错误"), QStringLiteral("请先画一个标尺") );
    }
}

MainWindow::~MainWindow()
{
    QSettings settings( ".\\scale.ini", QSettings::IniFormat, this );

    settings.setValue("PDStage/Line", m_spinBoxLine->value());

    delete ui;
}
void MainWindow::loadImage()
{
    QString fileName = QFileDialog::getOpenFileName(this,
         QStringLiteral("Open Image"), ".\\", QStringLiteral("Image Files (*.png *.jpg *.bmp)"));
    if( !fileName.isEmpty () )
    {
        m_centerWidget->loadImage(fileName);
        m_centerWidget->update();
    }
}

void MainWindow::saveImagewithMark()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                               ".\\",
                               QStringLiteral("Images (*.jpg *.png *.bmp)"));
    if( !fileName.isEmpty () )
    {
        m_centerWidget->saveImage(fileName, 1);
    }
}
void MainWindow::saveImagewithoutMark()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                               ".\\",
                               QStringLiteral("Images (*.jpg *.png *.bmp)"));
    if( !fileName.isEmpty () )
    {
        m_centerWidget->saveImage(fileName, 0);
    }
}
